package com.lemon.exam.common.redis.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import reactor.core.publisher.Mono;

import java.time.Duration;

/**
 * Redis Lock 操作类 对象
 *
 * @author Lemon
 * @since 2025/7/4 18:11
 */
public final class LockOperations extends BaseOperations {
    public LockOperations(ObjectMapper objectMapper, ReactiveRedisTemplate<String, Object> template) {
        super(objectMapper, template);
    }

    /**
     * 加锁
     *
     * @param key     锁的key
     * @param timeout 锁的过期时间
     * @return 是否成功
     */
    public Mono<Boolean> lock(String key, Duration timeout) {
        return withRetry(
                template.opsForValue().setIfAbsent(key, "1", timeout).defaultIfEmpty(false),
                "redis lock lock key: %s".formatted(key)
        ).onErrorResume(err -> Mono.just(false));
    }

    /**
     * 解锁
     *
     * @param key 锁的key
     * @return 是否成功
     */
    public Mono<Boolean> unlock(String key) {
        return withRetry(
                template.delete(key).map(count -> count > 0),
                "redis lock unlock key: %s".formatted(key)
        ).onErrorResume(err -> Mono.just(false));
    }
}
